﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SimpleExpression;

namespace SimpleExpression
{
    public class OrderExpression : Expression
    {
        private SerializableDictionary<AttributeExpression, OrderType> properties;
        private EntityMetadata entityMetadata;

        public OrderExpression()
        {
            properties = new SerializableDictionary<AttributeExpression, OrderType>();    
        }

        public OrderExpression(EntityMetadata entityMetadata)
            :this()
        {
            this.entityMetadata = entityMetadata;
        }

        public void Add(string property)
        {
            this.Add(this.GetAttributeExpression(property), OrderType.ASC);
        }

        public void Add(string property, OrderType orderType)
        {
            this.Add(this.GetAttributeExpression(property), orderType);
        }

        public void Add(PropertyMetadata property)
        {
            this.Add(new AttributeExpression(property), OrderType.ASC);
        }

        public void Add(PropertyMetadata property, OrderType orderType)
        {
            this.Add(new AttributeExpression(property), orderType);
        }

        public void Add(AttributeExpression attribute)
        {
            properties.Add(attribute, OrderType.ASC);
        }

        public void Add(AttributeExpression attribute, OrderType orderType)
        {
            properties.Add(attribute, orderType);
        }

        public SerializableDictionary<AttributeExpression, OrderType> Properties
        {
            get
            {
                return this.properties;
            }
        }

        private AttributeExpression GetAttributeExpression(string name)
        {
            // Si se encuentra el physicalName entonces se agrega un AttributeExpression de lo contrario un ViewAttributeExpression
            switch (this.entityMetadata.Properties.Contains(name))
            {
                case MappingType.None:
                    break;
                case MappingType.Physical:
                    return new AttributeExpression(this.entityMetadata[name]);
                case MappingType.Platform:
                    return new ViewAttributeExpression(this.entityMetadata.Properties[name, MappingType.Platform]);
                default:
                    break;
            }

            throw new NotImplementedException();
        }

        #region Expression

        public override void Accept(ExpressionVisitor visitor)
        {
            visitor.Visit(this);
        }

        #endregion
    }
}
